package xyz.magicjson.core.model;

import lombok.Data;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * ESB消息模型，用于在ESB组件之间传递消息。
 * 消息包含头部、正文、属性和元数据等信息。
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Message implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 消息ID，全局唯一标识符
     */
    @Builder.Default
    private String id = UUID.randomUUID().toString();
    
    /**
     * 消息头部信息，包含路由、协议等信息
     */
    @Builder.Default
    private Map<String, String> headers = new HashMap<>();
    
    /**
     * 消息体，包含实际的业务数据
     */
    private Object payload;
    
    /**
     * 消息属性，用于存储消息处理过程中的临时数据
     */
    @Builder.Default
    private Map<String, Object> properties = new HashMap<>();
    
    /**
     * 元数据，包含消息的描述信息
     */
    @Builder.Default
    private Map<String, Object> metadata = new HashMap<>();
    
    /**
     * 消息创建时间戳
     */
    @Builder.Default
    private long timestamp = System.currentTimeMillis();
    
    /**
     * 消息过期时间戳
     */
    private Long expiration;
    
    /**
     * 是否为加密消息
     */
    private boolean encrypted;
    
    /**
     * 消息协议
     */
    @Builder.Default
    private String protocol = "http";
    
    /**
     * 源服务名称
     */
    private String sourceService;
    
    /**
     * 目标服务名称
     */
    private String targetService;
    
    /**
     * 设置消息头部
     */
    public Message addHeader(String key, String value) {
        this.headers.put(key, value);
        return this;
    }
    
    /**
     * 设置消息属性
     */
    public Message addProperty(String key, Object value) {
        this.properties.put(key, value);
        return this;
    }
    
    /**
     * 设置元数据
     */
    public Message addMetadata(String key, Object value) {
        this.metadata.put(key, value);
        return this;
    }
    
    /**
     * 检查消息是否过期
     */
    public boolean isExpired() {
        return expiration != null && System.currentTimeMillis() > expiration;
    }
} 